package com.kpp.socket;

import java.awt.font.TextMeasurer;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.jws.Oneway;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import sun.management.counter.Variability;

//ws://192.168.1.171:8080/Socket_Demo1/ws
//ws://127.0.0.1:8087/Demo1/ws/张三
@ServerEndpoint("/ws/{userID}")
public class WSServer {
	private String userId;
	// 在线人数
	private static int onlineCount = 0;
	
	// 在线用户数组，使用map替代
	//private static CopyOnWriteArraySet<WSServer> webSocketSet = new CopyOnWriteArraySet<>();
	
	// 会话和用户ID绑定保存
	private static Map<String, Session> routeTable = new HashMap<>();
	
	
	//连接打开时执行
	@OnOpen
	public void onOpen(@PathParam("userID") String user, Session session) {
		// 记录当前用户ID
		userId = user;
		// 将用户ID和会话保存到map集合（userID是唯一的）
		routeTable.put(userId, session);
		//webSocketSet.add(this);
		addOnlineCount();
		System.out.println(user + " 上线 ... 现在 " + getOnlineCount() + " 人在线");
	}
	
	//收到消息时执行
	@OnMessage
	public void onMessage(String message, Session session) throws IOException {
		System.out.println(userId + "：" + message);
		// 心跳包
		if ("HeartBeat".equals(message)) {
			session.getBasicRemote().sendText("HeartBeat");
			return;
		}
		// 转发（群发）给其他用户
		this.massSend(message);
		//return "服务端onMessage" + "：" + message;
	}
	
	
	//连接关闭时执行
	@OnClose
	public void onClose(@PathParam("userID") String user, Session session, CloseReason closeReason) throws IOException {
		//webSocketSet.remove(session);
		System.out.println(String.format("Session %s 关闭； 原因： %s", user, closeReason));
		// 离线删除用户
		routeTable.remove(user);
		subOnlineCount();
		System.out.println(user + "离线 ... " + "当然在线 " + onlineCount + "人");
		session.close();
	}

	//连接错误时执行
	@OnError
	public void onError(Throwable t) {
        t.printStackTrace();
	}
	
	// 发送消息
	public void sendMessage(String user,String message) throws IOException {
		Session ses = (Session)routeTable.get(user);
		// 给对话者发消息
		ses.getBasicRemote().sendText(message);
	}
	
	// 群发消息
	public void massSend(String message) throws IOException {
		for (Map.Entry<String, Session> entry : routeTable.entrySet()) {
			String id = entry.getKey();
			// 群发给除当前用户外的其他用户
			if (this.userId != id) {
				Session ses = entry.getValue();
				if (ses.isOpen()) {
					ses.getBasicRemote().sendText(message);
				}
			}
		} 
	}
	
	// 获取在线人数
	public static synchronized int getOnlineCount() {
		return WSServer.onlineCount;
	}
	
	// 在线人数加一
	public static synchronized void addOnlineCount() {
		WSServer.onlineCount++;
	}
	
	// 在线人数减一
	public static synchronized void subOnlineCount() {
		WSServer.onlineCount--;
	}
	
}
